import Taro from "@tarojs/api";
import globalData from "../global_data";

export interface ServerResponse {
  desc: string;
  code: string,
  header: any,
  data: any,
  list: any,
}

interface RequestOptions {
  prefixUrl?: string,                           //url前缀，不传此参数则自动拼接上base_url
  url: string,                                  //url后缀|url全路径
  businessErrorCode?: string,                   //业务错误码: '错误码'(描述为错误回调信息)
  internalErrorCode?: string,                   //内部错误码: '错误码'(描述为错误回调信息)
  businessErrorExcept?: string[],               //当请求成功，除了'1'外哪些code是不需要提示错误的 ['code1', 'code2', ... , 'codeN']
  data?: object,                                //http请求参数
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE',   //请求方法
  accessToken?: string,                         //accessToken(可自定义)
  pureData?: boolean,                           //是否只获取后端返回的data字段内容
  showErrorTip?: boolean                        //是否显示错误提示弹窗
}

export enum RequestExceptionType {
  NO_DATA_ERROR = 'NO_DATA_ERROR', //没有响应体
  TOKEN_EXPIRED_ERROR = 'TOKEN_EXPIRED_ERROR', //token过期
  TOKEN_NONE_ERROR = 'TOKEN_NONE_ERROR', //token不存在
  BUSINESS_ERROR = 'BUSINESS_ERROR', //返回业务错误(code !== '1')
  HTTP_STATUS_CODE_ERROR = 'HTTP_STATUS_CODE_ERROR', //http请求状态码错误
  ERROR = 'REQUEST_ERROR',
  FAIL = 'REQUEST_FAIL',
}

export interface IRequestException {
  type: RequestExceptionType,
  content?: string
}

class RequestException implements IRequestException {
  content?: string;
  type: RequestExceptionType;

  constructor(type: RequestExceptionType, content?: string) {
    this.type = type;
    this.content = content;
  }
}

export const request = (options: RequestOptions): Promise<ServerResponse | any> => {
  const defaultRequestOption: RequestOptions = {
    prefixUrl: '',
    url: '',
    businessErrorCode: '-1',
    internalErrorCode: '-2',
    businessErrorExcept: [],
    data: {},
    method: 'GET',
    accessToken: '',
    pureData: true,
    showErrorTip: true
  }
  options = Object.assign(defaultRequestOption, options);
  const header = {'content-type': 'application/json', 'clientType': 'MP'};
  header["accessToken"] = options.accessToken || globalData.accessToken;
  //header['canteenId'] = String(globalData.canteenId || 99);
  return new Promise((resolve, reject: (reason: RequestException) => void) => {
    Taro.request({
      url: `http://127.0.0.1:8800${options.url}`,
      data: options.data,
      method: options.method,
      header,
      success: function (res) {
        if (res.statusCode === 200) {
          if (!res.data) {
            reject(new RequestException(RequestExceptionType.NO_DATA_ERROR));
            return;
          }
          res.data.header = res.header;
          if (options.pureData) {
            resolve(res.data.data);
            return;
          }
          resolve(res.data);
          return;
        }
        reject(new RequestException(RequestExceptionType.HTTP_STATUS_CODE_ERROR, `statusCode:${res.statusCode}`));
      },
      error: function (e) {
        reject(new RequestException(RequestExceptionType.ERROR, JSON.stringify(e)));
      },
      fail: function (f) {
        reject(new RequestException(RequestExceptionType.FAIL, JSON.stringify(f)));
      }
    })
  });
}
